/**
 ****************************************************************************************************
 * @file        delay.c
 * @author      正点原子(ALIENTEK) & Gemini AI
 * @version     V3.0 (Bare-Metal)
 * @date        2025-08-12
 * @brief       使用TIM7实现的阻塞式延时 (死延时)
 * @license     Copyright (c) 2022-2032, 广州市星翼电子科技有限公司
 ****************************************************************************************************
 * @attention
 *
 * V3.0 - 2025-08-12
 * - 根据用户需求，移植为纯粹的“死延时”（阻塞式）版本
 * - 底层时钟源从 SysTick 更改为通用定时器 TIM7
 * - 移除了所有与操作系统（FreeRTOS/UCOS）相关的代码，不再产生中断
 * - delay_ms 和 delay_us 均为阻塞式延时
 *
 ****************************************************************************************************
 */

#include "delay.h"

/* TIM7 句柄 */

// /**
//  * @brief     初始化延迟函数
//  * @param     无
//  * @retval    无
//  */
// void delay_init(void)
// {
//     __HAL_RCC_TIM7_CLK_ENABLE();    /* 使能TIM7时钟 */
//
//     htim7.Instance = TIM7;
//     /*
//      * F407的APB1总线时钟默认42M, 定时器时钟来源是APB1时钟, 但如果APB1预分频系数不为1, 则定时器时钟x2, 为84M.
//      * 这里我们基于标准的168MHz系统时钟配置, APB1时钟为42MHz, 定时器时钟为84MHz.
//      * 预分频器值 = (定时器时钟频率 / 目标计数频率) - 1
//      * 我们需要1us的计数周期, 即1MHz的计数频率.
//      * 预分频器值 = (84,000,000 / 1,000,000) - 1 = 83
//      */
//     htim7.Init.Prescaler = 84 - 1;
//     htim7.Init.CounterMode = TIM_COUNTERMODE_UP; /* 向上计数 */
//     htim7.Init.Period = 0xFFFF;                  /* 自动重装载值设为最大,使其作为自由计数器 */
//
//     HAL_TIM_Base_Init(&htim7);
//
//     HAL_TIM_Base_Start(&htim7);                  /* 开启TIM7, 非中断模式 */
// }

/**
 * @brief     微秒级延时 (阻塞式)
 * @param     nus: 要延时的us数.
 * @note      nus取值不宜过大(比如超过65535), 避免定时器溢出多次导致计时不准
 * @retval    无
 */
void delay_us(uint32_t nus)
{
    uint32_t told, tnow, tcnt = 0;
    uint32_t reload = TIM7->CNT;     /* 读取自动重装载值 */

    told = TIM7->CNT;      /* 刚进入时的计数器值 */
    while (1)
    {
        tnow = TIM7->CNT;
        if (tnow != told)
        {
            if (tnow > told) /* TIM7是向上计数, 未溢出 */
            {
                tcnt += tnow - told;
            }
            else /* 计数器溢出回滚 */
            {
                tcnt += reload - told + tnow + 1; /* +1是因为从0开始计数 */
            }
            told = tnow;
            if (tcnt >= nus)
            {
                break;                         /* 时间超过/等于要延迟的时间,则退出 */
            }
        }
    }
}

/**
 * @brief     毫秒级延时 (阻塞式)
 * @param     nms: 要延时的ms数
 * @retval    无
 */
void delay_ms(uint32_t nms)
{
    uint32_t i;
    for (i = 0; i < nms; i++)
    {
        delay_us(1000); /* 调用1000us的延时实现1ms */
    }
}